import React, {Fragment, PureComponent} from 'react';
import { connect } from '@@/plugin-dva/exports';
import styles from './index.less';
import Cookie from '@/utils/cookie.js';
import u325 from "./img/u325.png";
import { history } from 'umi';
import {Modal, message,Upload,Input, Tabs  } from "antd";
import UserFeedBack from "@/pages/HomePage/UserFeedback";
import Robot from '@/assets/images/bonceChatGpt/kefuPh.png';
import RayRobot from '@/assets/images/bonceChatGpt/rayKefu.png';
import User from '@/assets/images/bonceChatGpt/user.png';
import Word from '@/assets/images/bonceChatGpt/word.png';
import Pdf from '@/assets/images/bonceChatGpt/pdf.png';
import Txt from '@/assets/images/bonceChatGpt/txt.png';
import Ppt from '@/assets/images/bonceChatGpt/ppt.png';
import Excel from '@/assets/images/bonceChatGpt/excel.png';
import Csv from '@/assets/images/bonceChatGpt/csv.png';
import tabF from '@/assets/images/bonceChatGpt/tabF.png';
import moment from 'moment/moment';
import { RobotRes } from '@/components/boncGpt/RobotRes'
import { DoubleRightOutlined,FolderAddOutlined,CloseCircleOutlined, CheckOutlined,CloseOutlined } from '@ant-design/icons';
import PreSearchComponent from "@/components/boncGpt/preSearchComponent";
import MarkdownText from "@/components/boncGpt/markdownText";
import TabTop from "@/components/boncGpt/TabTop";
const { TextArea } = Input;
class NewTalk extends PureComponent {
  allow = true;
  constructor(props) {
    super(props);
    this.state = {
      userImg: false,
      loading: false,
      messageContentHeight:"",
      query:"",
      content:{},
      vis:false,
      title:'新对话',
      openModel: false,
      inputDisabled:false,
      NewTalkStatus:true,
      editTitle:'新对话',
      showEditTitle:false,
      dots:"",
      editLogo:false,
      scroll:false,
      bottomScroll:false,
      fileList:[], //文件列表
      maxSize:50 * 1024 * 1024,
    };
    this.messageContentRef = React.createRef();
    this.intervalId = null;
    this.timeOutId = React.createRef();
  }

  //初始化
  componentDidMount() {
    const textarea = document.getElementById('myTextarea');
    let that = this
    textarea.addEventListener('keydown', function(event) {
      if (event.key === 'Enter') {
        if (event.ctrlKey) {
          that.setState((state)=>({
            query: state.query+"\n"
          }))
        } else {
          event.preventDefault();
        }
      }
    });

    this.messageContentRef.current.addEventListener('scroll', this.handleScroll);
    this.intervalId = setInterval(() => {
      this.setState(prevState => ({
        dots: prevState.dots.length < 3 ? prevState.dots + '.' : '',
      }));
    }, 500);
    const { title,dialogueId,userId } = this.props;
    //暂时注释掉也好用
    // this.getHeight()
    if(title!=="新会话"&&dialogueId===""&&userId!==""){
      this.sendMessage_pre(title)
    }
  }

  //快速定位到底部
  getHeight = () => {
    this.setState({
      messageContentHeight: this.messageContentRef.current.scrollHeight,
    });
    this.messageContentRef.current.scrollTop = this.messageContentRef.current.scrollHeight;
  };

  //页面对话更新时定位到底部
  componentDidUpdate(prevProps, prevState) {
    const {messageList,}=this.props
    if (!prevProps.isLoading && this.props.isLoading) {
      this.intervalId = setInterval(() => {
        this.setState(prevState => ({
          dots: prevState.dots.length < 3 ? prevState.dots + '.' : '',
        }));
      }, 500);
    } else if (prevProps.isLoading && !this.props.isLoading) {
      clearInterval(this.intervalId);
    }
    if(messageList.length!==prevProps.messageList.length) {
      this.handleScroll()
    }
    if (this.state.NewTalkStatus) {
      this.setState({
        NewTalkStatus:false,
      })
      if (messageList.length && (prevState.title !== messageList[0].resp)) {
        let title =JSON.parse(messageList[0].resp).replace(/\n|\\\\n/g, '');
        this.setState({
          title: title,
          editTitle: title,
        })
      }
  }
}
  handleScroll=()=>{
    const  {scrollTop, scrollHeight, clientHeight} = this.messageContentRef.current;
   this.setState({
     scroll: scrollHeight-scrollTop>clientHeight,
     bottomScroll:scrollHeight-scrollTop>clientHeight+30
   })
  }
  componentWillUnmount() {
    clearInterval(this.intervalId);
    if(this.timeOutId.current) clearTimeout(this.timeOutId.current)
    this.messageContentRef.current.removeEventListener('scroll', this.handleScroll);
  }

  back = () => {
    history.push({
      pathname: '/homePage',
    });
  }
  onChangeInput=(e)=>{
    this.setState({
      query: e.target.value,
    })
  }
  addLog=(res)=>{
    const {dispatch,messageList}= this.props
    dispatch({
      type: 'intellectAssistant/fetchAddLog',
      payload:res,
      callback:(dialogueId)=>{
        if(messageList.length===1){
          dispatch({
            type: 'intellectAssistant/updateDialogue',
            payload: {
              sender:Cookie.get('userName'),
              id:dialogueId,
              title:JSON.parse(messageList[0].resp).replace(/\n|\\\\n/g, ''),
            },
            noMsg:true
          });
        }
      }
    })
  }
  sendMessage_pre=async (valueText,e)=>{
    const { loading,fileList } = this.state;
    const { dispatch,isLoading,dialogFlag } = this.props;
    let that = this;
    let query = valueText.trim();
    const regex = /^[\n\\\\n ]+$/;
    if(regex.test(query)) return;
    if((loading&&isLoading&&e&&e.key === 'Enter'&&!e.ctrlKey &&query)||(loading&&isLoading&&!e&&query)){
      return Modal.confirm({
        title:"提示",
        content:"AI助手正在回答中，请耐心等待",
        centered:true,
        okText:"提问新问题",
        onOk(){
          return new Promise((resolve=>{
            resolve()
            that.setState({
              loading:false
            },()=>{
              that.sendMessage_pre(query,e)
            })
          }))
        }
      })
    }
    if(!query) return
    if(this.timeOutId.current){
      clearTimeout(this.timeOutId.current)
    }
    if ((!e&&query)||(e.key === 'Enter'&&!e.ctrlKey &&query)) {
      dispatch({
        type: 'intellectAssistant/updateState',
        payload: {
          isLoading: true,
        }
      });
      const createTime = moment().format('YYYY-MM-DD    HH:mm:ss');
      dispatch({
        type: 'intellectAssistant/addMessageListState',
        payload: {
          resp: JSON.stringify(query), //消息
          character: 'user', //机器人robot还是用户自己user
          createTime,
          files:dialogFlag==="1"&&fileList.length>0?fileList:undefined
        },
        callback: (res) => {
          this.setState({
            query: '',
            fileList:[],
            loading:true,
          },()=>{
            this.addLog(res)
          });
          //长时间不响应也消除
          this.timeOutId.current =setTimeout(()=>{
            this.setState({
              loading: false,
            })
          },1000 * 360)
        },
      });

    }
  }
  onOk=(resp)=>{
    const { dispatch } = this.props;
    if(this.timeOutId.current){
      clearTimeout(this.timeOutId.current)
    }
    dispatch({
      type: 'intellectAssistant/updateState',
      payload: {
        isLoading: true,
      }
    });
    this.setState({
      vis:false,
      loading:true
    },()=>{
      this.sendMessage_fun(resp)
    })
    //长时间不响应也消除
    this.timeOutId.current =setTimeout(()=>{
      this.setState({
        loading: false,
      })
    },1000 * 360)
  }
  onCancel=()=>{
    this.setState({
      vis:false,
      content:{}
    })
  }
  handelOk = () => {
    this.setState({openModel: true})
  }

  submitFeedback = (feedbackText)=>{
    const { dispatch } = this.props;
    dispatch({
      type: 'intellectAssistant/fetchFeedBack',
      payload: {
        question:'',
        answer:'',
        islike:'',
        feedback: feedbackText,
      },
      callback: () => {
        this.setState({
          msgVisible:false,
          type:""
        });
      },
    });
  }
  handelCancel = () => {
    this.setState({openModel: false})
  }

  sendMessage_fun=(resp)=>{
    const { dispatch } = this.props;
    dispatch({
      type: 'intellectAssistant/fetchInformationData',
      payload: resp,
      callback: (res) => {
        this.setState({
          loading: false,
        },()=>{
          if(!res.error) this.addLog(res)
        });
      },
    });
  }



  back = () => {
    const { dispatch } = this.props;
    dispatch({
      type: 'intellectAssistant/updateState',
      payload:{
        title:"新会话",
        dialogueId:"",
        messageList: []
      }
    })
    history.push({
      pathname: '/homePage',
    });
  }


  clickTitle = () => {
    // 如果没有对话id直接返回
    console.log(this.props.dialogueId);
    if(this.props.dialogueId==='')return message.info('请先开始对话再设置标题')
    this.setState({
      showEditTitle:true,
      editTitle:this.props.title
    })
  }
  setTitle = () => {
    const { dispatch,dialogueId } = this.props;
    if(this.state.editTitle.length>20||this.state.editTitle==="") {
      return message.info('会话名称不能为空且不能超过20个字')
    }else {
      //  修改标题后执行
      dispatch({
        type: 'intellectAssistant/updateDialogue',
        payload: {
          sender:Cookie.get('userName'),
          id:dialogueId,
          title:this.state.editTitle,
        },
        callback:(code)=>{
          if(code===200){
            this.setState({
              showEditTitle:false,
              NewTalkStatus:false
            })
          }
        }
      });
    }
  }
  cancelModal=()=>{
    this.setState({
      title:this.state.editTitle,
      showEditTitle:false,
      NewTalkStatus:false,
    })
  }

  exportDown = (reaL) => {
    const { dispatch } = this.props
    dispatch({
      type: 'intellectAssistant/fetchTableDownload',
      payload: {
        name:reaL.kpi_name,
        final_kpi_sql:reaL?.final_kpi_sql||"",
        kpi_sql :reaL?.kpi_sql ||"",
        vtable_sql  :reaL?.vtable_sql  ||"",
      },
    });
  }
  manageLeve=(file)=>{
    this.setState({
      editLogo: false,
    })
  }
  beforeUpload=(file)=>{
    const { maxSize,fileList } = this.state
    if (
      !/\.(xlsx|xls|XLSX|XLS|txt|TXT|docx|DOCX|doc|DOC|pdf|PDF|CSV|csv)$/.test(
        file.name
      )
    ) {
      Modal.error({
        title: "错误",
        content: "上传文件只能为excel,word,pdf,txt,csv文件",
      });
      this.allow = false;
    } else {
      let size = fileList?.reduce((acc, item)=>acc+item?.size,0)||0
      if (size+file.size > maxSize) {
        Modal.error({
          title: "错误",
          content: "上传文件大小已经超过最大50M限制",
        });
        this.allow = false;
      }
    }
    return false;
  }
  handleChange=(info)=>{
    const { fileList } = this.state;
    let newFile = [...fileList,info.file]
    if (!this.allow) {
      this.allow = true;
      return;
    }
    this.setState({
        fileList:newFile,
      })
  }
  deleteFile=(index)=>{
    const { fileList } = this.state
    fileList.splice(index,1);
    this.setState({
      fileList:fileList,
    })
  }
  downloadProfile=(fileName)=>{
    const { dispatch } = this.props;
    dispatch({
      type:"intellectAssistant/fetchFileDownload",
      payload:fileName
    })
  }
  switchChange=()=>{
    const { dispatch,checkedSwitch } = this.props;
    dispatch({
      type:"intellectAssistant/updateState",
      payload: {
        checkedSwitch: !checkedSwitch,
      }
    })
  }
  render() {
    const {openModel,editTitle,query, loading,editLogo,scroll,bottomScroll,fileList } =this.state
    const createTime = moment().format('YYYY-MM-DD    HH:mm:ss');
    const { messageList,dispatch, title,dialogueId,isLoading,dialogFlag,pageContent,checkedSwitch,pageFileList} = this.props;
    function getPhoto(fileName){
      let unit = fileName?.split('.')?.at(-1)?.toUpperCase();
      if(unit.includes('XLS')){
        return Excel;
      }else if(unit.includes('TXT')){
        return Txt;
      }else if(unit.includes('DOC')){
        return Word;
      }else if(unit.includes("PDF")){
        return  Pdf;
      }else if(unit.includes("PPT")){
        return  Ppt;
      }else if(unit.includes("CSV")){
        return  Csv;
      }
    };
    function getFileSize(size){
      let kbSize = (size/1024).toFixed(2)
      let mbSize = (kbSize/1024).toFixed(2)
      if(kbSize<1024){
        return kbSize + "KB"
      }else {
        return mbSize + "Mb"
      }
    };
    const items = [
      {
        key: '1',
        label: '参考资料',
        children: (
          <div className={styles.profileArticle}>
            {pageContent.length > 0 && pageContent.map((profile, profileIndex) => {
              if(profile.metadata && profile.metadata.source) {
                return (
                  <div key={profileIndex}>
                    <div className={styles.articleTitle}>
                      {`文件[${profileIndex + 1}]`}
                      <span onClick={() => this.downloadProfile(profile?.metadata?.source)}>
                      {profile?.metadata?.source}
                    </span>)
                    </div>
                    <div className={styles.articleContent}>
                      {profile.page_content}
                    </div>
                  </div>
                );
              }else {
                return (
                  <div key={profileIndex}>
                    <div className={styles.articleContent}>
                      {profile}
                    </div>
                  </div>
                );
              }
            })||(<div>暂无参考资料！</div>)}
          </div>
        ),
      },
      {
        key: '2',
        label: '会话文件',
        children: (
          <div className={styles.profileArticle}>
            {pageFileList.length > 0 && pageFileList.map((file, fileIndex) => {
              return (
                <div className={styles.fileItemGpt} key={fileIndex}>
                  <img className={styles.fileLeft} src={getPhoto(file.name)} alt="" />
                  <div className={styles.fileRight}>
                    <div className={styles.fileNameGpt}>{file.name}</div>
                    <div className={styles.fileSizeGpt}>{getFileSize(file.size)}</div>
                  </div>
                </div>
              );
            })||(<div>暂无会话文件！</div>)}
          </div>
        ),
      },
    ];
    return (
      <div className={styles.content}>
        <div className={styles.rightIconUser}>
          {dialogFlag==="1"?(<img className={styles.feedBack} src={tabF} alt="" onClick={this.switchChange}/>):""}
        </div>
        <div className={styles.contentPage}>
          <div className={styles.topTab}>
            <TabTop dispatch={dispatch}/>
          </div>
          <div onMouseLeave={this.manageLeve} onClick={() => this.setState({editLogo: !editLogo})}
               style={{cursor: dialogueId ? "pointer" : "not-allowed"}} className={styles.title}
          ><span className={styles.name}
                 title={title && title.slice(0, 20) || ""}>{title && title.slice(0, 20) || ""}</span><span
            className={styles.logo}>{">"}
            {editLogo && dialogueId ? <div className={styles.editModal} onClick={this.clickTitle}>修改名称</div> : ""}
          </span>

          </div>
          <Modal width={600} open={this.state.showEditTitle} onOk={this.setTitle} onCancel={this.cancelModal}
                 okText="确定" cancelText="取消" title="修改名称">
            <Input
              value={editTitle.slice(0, 20)}
              onChange={(e) => this.setState({editTitle: e.target.value})}
              style={{width: '100%'}}
            />
            <div style={{color: "#c91717", fontSize: "12px"}}>最大长度为20</div>
          </Modal>
          <div id="messageContentId" className={styles.messageContent} ref={this.messageContentRef}>
            <div className={styles.robot}>
              <div className={styles.item}>
                <div className={styles.logo}>
                  <img src={RayRobot} alt=""/>
                </div>
                <div className={styles.messageItem}>
                  <div className={styles.topSearch}>
                    <div
                      className={styles.titleQuestion}>Hi,欢迎使用智能取数小助手，请随时告诉我你的需求，让我们一起开始吧！
                    </div>
                  </div>
                </div>
              </div>
              <div className={styles.createTime}>{createTime}</div>
            </div>
            {messageList.map((item, index) => {
              return (
                <div
                  key={index}
                  className={
                    item.character === 'user'
                      ? `${styles.user}`
                      : `${styles.robot}`
                  }
                >
                  <div className={styles.item}>
                    {item.character === 'robot' ? (
                      <div className={styles.logo}>
                        {messageList.length - 1 === index ? (<img src={Robot} alt=""/>) : (
                          <img src={RayRobot} alt=""/>)}
                      </div>
                    ) : (
                      ''
                    )}
                    <div className={styles.messageItem}>
                      <div>
                        {item.character === 'user' ?
                          <div className={styles.response}>{JSON.parse(item.resp)}</div> : !item.predictStatus ? (
                            <div className={styles.response}>
                           <RobotRes handleScroll={this.getHeight} index={index} item={item} content={item.resp}
                                    dispatch={this.props.dispatch}/>
                            </div>
                          ) : item.codeInformation ? (<div className={styles.response}>{item.codeInformation}</div>) :
                            <div className={styles.response}>
                              {item.resp.resp_code === "00006" ? <MarkdownText
                                  bottomScroll={bottomScroll}
                                  handleScroll={this.getHeight}
                                  onOk={this.onOk}
                                  item={item}
                                  markdown={item.resp?.ai_desc}
                                  dispatch={this.props.dispatch}/> :
                                <PreSearchComponent
                                  bottomScroll={bottomScroll}
                                  handleScroll={this.getHeight}
                                  exportDown={this.exportDown}
                                  onOk={this.onOk}
                                  itemContent={item}
                                  dispatch={this.props.dispatch}/>
                              }
                            </div>}
                      </div>
                    </div>
                    {item.character === 'user' ? (
                      <div className={styles.logo}>
                        <img src={User} alt=""/>{' '}
                      </div>
                    ) : (
                      ''
                    )}
                  </div>
                  {item.character === 'user' ? (
                    <div className={styles.fileContent}>
                      {item.files && item.files.length > 0 && item.files.map((item11, index11) => {
                        return <div key={index11} className={styles.fileItem}>
                          <div title={item11.name} className={styles.fileName}>
                            <img src={getPhoto(item11.name)} alt=""/>
                            {item11.name}
                          </div>
                          <div className={styles.fileSize}>{getFileSize(item11.size)}</div>
                        </div>
                      })}
                    </div>
                  ) : ""}
                  {
                    item.character === 'user' ? (
                      <div className={styles.createTime}>{item.createTime}</div>
                    ) : (
                      ''
                    )
                  }
                </div>
              )
                ;
            })}
            <div
              className={styles.loadingContainer}
              style={{display: loading && isLoading ? 'block' : 'none'}}
            >
              <div className={styles.logo}>
                <img src={Robot} alt=""/>
              </div>
              <div className={styles.loading}>
                {this.state.dots}
              </div>
            </div>
          </div>
          <div style={{visibility:scroll?"visible":"hidden"}} className={styles.arrowFa}>
            <div onClick={this.getHeight} className={styles.arrowsBottom}><DoubleRightOutlined/></div>
          </div>
          <div className={styles.query}>
            <div className={styles.sandMessage}>
              {
                dialogFlag === "1" ? (<div className={styles.funList}>
                  <Upload showUploadList={false} multiple={true} beforeUpload={this.beforeUpload}
                          onChange={this.handleChange}>
                    <div className={styles.fileMenu}><FolderAddOutlined/>文件上传</div>
                  </Upload>
                </div>) : ""
              }
              <div className={styles.topContent}>
                <div className={styles.fileContent}>
                  {fileList.length > 0 && fileList.map((item11, index11) => {
                    return <div key={index11} className={styles.fileItem}>
                      <CloseCircleOutlined className={styles.closeFile} onClick={() => this.deleteFile(index11)}/>
                      <div title={item11.name} className={styles.fileName}>
                        <img src={getPhoto(item11.name)} alt=""/>
                        {item11.name}
                      </div>
                      <div className={styles.fileSize}>{getFileSize(item11.size)}</div>
                    </div>
                  })}
                </div>
                <TextArea
                  className={styles.myTextArea}
                  placeholder={'输入你想查的，小助手使用各种能力'}
                  autoFocus={true}
                  id="myTextarea"
                  style={{backgroundColor: this.state.inputDisabled ? '#f5f5f5' : '#fff'}}
                  value={query}
                  onChange={this.onChangeInput}
                  autoSize
                  onKeyDown={(e) => this.sendMessage_pre(query, e)}
                />
              </div>

              <div className={styles.sandMessageImg} onClick={() => this.sendMessage_pre(query)}>
                <img src={u325} alt=""/>
              </div>
            </div>
          </div>
        </div>
        <div className={styles.profile}>
          {dialogFlag === "1" && checkedSwitch ? <div className={styles.profileContent}>
              <Tabs destroyInactiveTabPane={true} defaultActiveKey="1" items={items} />
            </div> : ""}
        </div>
        <UserFeedBack openModel={openModel} handelOk={this.handelOk} handelCancel={this.handelCancel}
                      submitFeedback={this.submitFeedback}/>
      </div>
    );
  }
}

//这里的intellectAssistant 是创建models时取的model名   namespace："这里的intellectAssistant"  umi会自动识别该字段进行如下解构
export default connect(({intellectAssistant, login}) => ({
  messageList: intellectAssistant.messageList,
  dialogueId: intellectAssistant.dialogueId,
  title: intellectAssistant.title,
  isLoading: intellectAssistant.isLoading,
  dialogFlag: intellectAssistant.dialogFlag,
  pageContent: intellectAssistant.pageContent,
  checkedSwitch: intellectAssistant.checkedSwitch,
  pageFileList: intellectAssistant.pageFileList,
}))(NewTalk);
